﻿/*
 * @author: wizardc
 */

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

namespace Dou.Utils
{
    /// <summary>
    /// HTTP 工具类
    /// </summary>
    public static class HttpUtil
    {
        /// <summary>
        /// GET 请求
        /// </summary>
        public static void Get(string uri)
        {
            Get(uri, null, null, 15);
        }
        
        /// <summary>
        /// GET 请求
        /// </summary>
        public static void Get(string uri, Action<int, string> onComplete, Action<int, string> onError, int timeout, int reconnectCount)
        {
            void ErrorHandler(int responseCode, string error)
            {
                --reconnectCount;
                if (reconnectCount <= 0)
                {
                    onError?.Invoke(responseCode, error);
                } else
                {
                    Get(uri, onComplete, ErrorHandler, timeout);
                }
            }
            Get(uri, onComplete, ErrorHandler, timeout);
        }

        /// <summary>
        /// GET 请求
        /// </summary>
        public static void Get(string uri, Action<int, string> onComplete, Action<int, string> onError, int timeout)
        {
            CoroutineUtil.StartCoroutine(WebGet(uri, onComplete, onError, timeout));
        }
        
        private static IEnumerator WebGet(string uri, Action<int, string> onComplete, Action<int, string> onError, int timeout)
        {
            var request = UnityWebRequest.Get(uri);
            request.method = UnityWebRequest.kHttpVerbGET;
            request.timeout = timeout;
            yield return request.SendWebRequest();
            if (request.isHttpError || request.isNetworkError)
            {
                onError?.Invoke((int) request.responseCode, request.error);
            }
            else
            {
                onComplete?.Invoke((int) request.responseCode, request.downloadHandler.text);
            }
        }

        /// <summary>
        /// POST 请求
        /// </summary>
        public static void Post(string uri, Dictionary<string, string> data)
        {
            Post(uri, data, null, null, 15);
        }

        /// <summary>
        /// POST 请求
        /// </summary>
        public static void Post(string uri, Dictionary<string, string> data, Action<int, string> onComplete, Action<int, string> onError, int timeout, int reconnectCount)
        {
            void ErrorHandler(int responseCode, string error)
            {
                --reconnectCount;
                if (reconnectCount <= 0)
                {
                    onError?.Invoke(responseCode, error);
                } else
                {
                    Post(uri, data, onComplete, ErrorHandler, timeout);
                }
            }
            Post(uri, data, onComplete, ErrorHandler, timeout);
        }

        /// <summary>
        /// POST 请求
        /// </summary>
        public static void Post(string uri, Dictionary<string, string> data, Action<int, string> onComplete, Action<int, string> onError, int timeout)
        {
            CoroutineUtil.StartCoroutine(WebPost(uri, data, onComplete, onError, timeout));
        }
        
        private static IEnumerator WebPost(string uri, Dictionary<string, string> data, Action<int, string> onComplete, Action<int, string> onError, int timeout)
        {
            var form = new WWWForm();
            if (data != null)
            {
                foreach (var item in data)
                {
                    form.AddField(item.Key, item.Value);
                }
            }
            var request = UnityWebRequest.Post(uri, form);
            request.timeout = timeout;
            request.method = UnityWebRequest.kHttpVerbPOST;
            yield return request.SendWebRequest();
            if (request.isHttpError || request.isNetworkError)
            {
                onError?.Invoke((int) request.responseCode, request.error);
            }
            else
            {
                onComplete?.Invoke((int) request.responseCode, request.downloadHandler.text);
            }
        }
    }
}
